#!/usr/bin/perl -w

##HACKABOT_HELP##
# Ping a group of people at once!
# !group group_name [ msg | --add nick1 [...] | --del nick1 [...] ]
# !group --list
##HACKABOT_HELP##

use strict;
use List::MoreUtils qw(uniq);
use Hackabot::Client;

my $hbc = Hackabot::Client->new;
my $msg = $hbc->readline;
my $nick = $hbc->sent_by;
my $chan = $hbc->channel;

if (not $msg) {
	exit;
}
elsif ($msg =~ /^--list\s*$/) {
    my $groups = list_groups();

    if (defined $groups) {
        print "send Groups: $groups\n";
    }
    else {
        print "send No groups defined!";
    }
}
elsif ($msg =~ /^(\S+)\s+--add\s+(.*\S)\s*$/) {
	my $group = $1;
	my $text = $2;

    my @list = split(/(\s+|,)/, $text);

	my $names = get_group($group);
	if (defined $names) {
        push @list, split(/,/, $names);
    }

	my $ret = add_group($group, cleanup(@list), $nick, $chan);
	print "send $nick: $ret\n";
}
elsif ($msg =~ /^(\S+)\s+--del(\s+(.*\S))?\s*$/) {
	my $group = $1;
	my $text = $3;
    my $ret;

	my $names = get_group($group);
	if (defined $names) {
        my %orig = ();
        my %del = ();

        foreach my $name (split(/,/, $names)) {
            $orig{$name} = 1;
        }

        if (defined $text) {
            foreach my $name (split(/(\s+|,)/, $text)) {
                if (not $orig{$name}) {
                    print "send $nick: '$name' is not in the group '$group'\n";
                    exit;
                }
                else {
                    $del{$name} = 1;
                }
            }
        }

        my @list = grep {!$del{$_}} keys(%orig);

        if (@list and keys(%del)) {
            $ret = add_group($group, cleanup(@list), $nick, $chan);
        }
        else {
            $ret = delete_group($group);
        }
    }
    else {
		$ret = "No such group '$group'\n";
	}

	print "send $nick: $ret\n";
}
else {
	$msg =~ /(\S+)\s*(\S*.*)/;
	my $group = $1;
	my $text = $2;
	my $names = get_group($group);

	if (not defined $names) {
		print "send No such group '$group'\n";
	}
	elsif ($text) {
		print "send $names: $text\n";
	}
	else {
		print "send $names\n";
	}
}

sub cleanup {
    my %seen = ();
    my @list = grep { /[^\s,]/ and !$seen{$_}++ } sort(@_);
    return join(",", @list);
}

sub list_groups {
    my $dbh = $hbc->dbi;
	my $sth = $dbh->prepare("SELECT name FROM `group`");
    my ($list, $row);

	$sth->execute();
    while ($row = $sth->fetchrow_hashref) {
        if (defined $list) {
            $list .= ", ".$row->{'name'};
        }
        else {
            $list = $row->{'name'};
        }
    }

    return $list;
}

sub get_group {
	my $group = shift;

    my $dbh = $hbc->dbi;
	my $sth = $dbh->prepare("SELECT name,names FROM `group` WHERE name = ?");
	$sth->execute($group);
	my $row = $sth->fetchrow_hashref;
	my $value;
	if (defined $row->{'names'}) {
		$value = $row->{'names'};
	}

	return $value;
}

sub add_group {
	my $group = shift;
	my $text = shift;
	my $nick = shift;
	my $chan = shift;

    my $dbh = $hbc->dbi;
	my $ret = "Successfully updated '$group'";
	$dbh->do("INSERT `group` (name, names, nick, chan, date)
       VALUES(?, ?, ?, ?, NOW()) ON DUPLICATE KEY UPDATE
       names = VALUES(names), nick = VALUES(nick),
       chan = VALUES(chan), date = VALUES(date)",
       undef, $group, $text, $nick, $chan)
       or $ret = "I'm a failure! I couldn't add it. :-(";

	return $ret;
}

sub delete_group {
	my $group = shift;

    my $dbh = $hbc->dbi;
	my $ret = "Deleted '$group'";
	$dbh->do("DELETE FROM `group` WHERE name = ?", undef, $group)
        or $ret = "I'm a failure! I couldn't delete it. :-(";

	return $ret;
}
